// utils/WssLogger.js
import WebSocket from 'ws';
import {createLogger} from "./Logger.js";
import {StrUtil} from "./StrUtil.js";

export class WssLogger {


    /**
     * @param {string} vopsToken 认证 token
     * @param {boolean} verbose 打印日志
     */
    constructor(vopsToken, verbose=false) {
        this.vopsToken = vopsToken;
        this.verbose = verbose;
        this.log = createLogger("WSS");
    }
    /**
     * 连接 WebSocket 并打印所有消息
     * @param {string} num - 项目num
     * @param {string} jobNum - 项目 下job num
     * @param {string} [env] - 构建环境
     */
    async connectAndListen(num, jobNum, env, options = {}) {
        const url = this.buildWssUrl(num, jobNum, env, options);
        this.log.info(`🔗 正在连接到: ${url}`);
        const ws = new WebSocket(url);

        ws.on('open', () => {
            this.log.success(' WebSocket 连接成功');
        });

        ws.on('message', (data) => {
            this.handleMessage(data.toString());
        });

        ws.on('close', (code, reason) => {
            this.log.error(` WebSocket 已关闭, code=${code}, reason=${reason}`);
        });

        ws.on('error', (err) => {
            this.log.error('⚠ WebSocket 错误:', err.message);
        });
    }
    async handleMessage(raw) {
        try {
            const parsed = JSON.parse(raw);
            if (parsed.type === "message") {
                // 把转义的 \n 替换成真正换行
                const formatted = parsed.message.replace(/\\n/g, "\n");
                console.log(formatted);
            } else {
                // console.log("收到非日志消息:", parsed);
            }
        } catch (err) {
            console.error("消息解析失败:", raw, err);
        }
    }

    /**
     * 获取 SonarQube 分析结果（从日志流里截取）
     * @param {string} num - 项目num
     * @param {string} jobNum - 项目下 job num
     * @returns {Promise<{bugs: number, coverage: number}>}
     */
    async fetchSonarResult(num, jobNum) {
        return new Promise((resolve, reject) => {
            let url = `wss://vops.hszq8.com/app/api/v1/console/log/${num}?job_num=${jobNum}&token=${this.vopsToken}`;
            this.log.log(`🔗 获取 SonarQube 日志: ${url}`);
            const ws = new WebSocket(url);
            ws.on('message', (data) => {
                try {
                    const parsed = JSON.parse(data.toString());
                    if (parsed.type === "message") {
                        const line = parsed.message.replace(/\\n/g, "\n");
                        const result = StrUtil.parseSonarLog(line);
                        if (result) {
                            this.log.log(` 捕获 SonarQube 结果: bugs=${result.bugs}, coverage=${result.coverage}`);
                            ws.close();
                            resolve(result);
                        }
                    }
                } catch (err) {
                    this.log.error("解析消息失败:", err.message);
                }
            });

            ws.on('close', () => {
                this.log.log(' WebSocket 已关闭');
            });

            ws.on('error', (err) => {
                this.log.error('⚠ WebSocket 错误:', err.message);
                reject(err);
            });
        });
    }

    buildWssUrl(num, jobNum, env, options = {}) {
        const normalizedEnv = typeof env === 'string' ? env.trim().toLowerCase() : '';
        const normalizedNum = this.normalizeValue(num);
        const normalizedJobNum = this.normalizeValue(jobNum);
        const query = new URLSearchParams();
        const channel = this.resolveChannel(normalizedEnv, options.channel);
        if (channel) {
            query.set('type', channel);
        }
        const effectiveJobNum = this.resolveJobNum({
            channel,
            normalizedNum,
            normalizedJobNum,
            override: options.jobNum
        });
        if (StrUtil.notNull(effectiveJobNum)) {
            query.set('job_num', effectiveJobNum);
        }
        if (StrUtil.notNull(this.vopsToken)) {
            query.set('token', this.vopsToken);
        }
        const pathId = normalizedNum || normalizedJobNum || effectiveJobNum;
        if (StrUtil.isNull(pathId)) {
            throw new Error('缺少日志编号，无法构建 WSS 链接');
        }
        const queryString = query.toString();
        const base = `wss://vops.hszq8.com/app/api/v1/console/log/${pathId}`;
        return queryString ? `${base}?${queryString}` : base;
    }

    resolveChannel(env, overrideChannel) {
        const normalizedOverride = this.normalizeValue(overrideChannel).toLowerCase();
        if (normalizedOverride) {
            return normalizedOverride;
        }
        if (env === 'ft') {
            // 发布单构建默认使用 release 通道
            return 'release';
        }
        return '';
    }

    resolveJobNum({channel, normalizedNum, normalizedJobNum, override}) {
        const normalizedOverride = this.normalizeValue(override);
        if (normalizedOverride) {
            return normalizedOverride;
        }
        if (channel === 'flow') {
            return normalizedNum;
        }
        if (StrUtil.notNull(normalizedJobNum)) {
            return normalizedJobNum;
        }
        return normalizedNum;
    }

    normalizeValue(value) {
        if (StrUtil.notNull(value)) {
            return String(value).trim();
        }
        return '';
    }
}
